﻿using System;
using System.Collections.Generic;
using Microsoft.Practices.Prism.ViewModel;

namespace Warehouse.Silverlight.Core.Infrastructure.Components
{
    public abstract class SearchParams : NotificationObject
    {
        private Dictionary<string, object> _last;
        private Dictionary<string, object> _current;
        private bool _isDefault; //if true: _current == _default
        private bool _hasChanges; //if true: _current != _last

        protected SearchParams()
        {
            _last = new Dictionary<string, object>();
            _current = new Dictionary<string, object>();
            foreach (var item in _default)
            {
                _last.Add(item.Key, item.Value);
                _current.Add(item.Key, item.Value);
            }
            _isDefault = true;
            _hasChanges = false;
        }

        protected abstract Dictionary<string, object> _default { get; }

        protected abstract bool CompareDictionaryValue(Dictionary<string, object> dict1, Dictionary<string, object> dict2);

        public object this[string key]
        {
            get
            {
                if (_current.ContainsKey(key))
                {
                    return _current[key];
                }
                else
                    throw new ArgumentOutOfRangeException(key);
            }
            set
            {
                if (_current.ContainsKey(key))
                {
                    if (_current[key] != value)
                    {
                        _current[key] = value;
                        RaisePropertyChanged(key);

                        IsDefault = CompareDictionaryValue(_current, _default);
                        HasChanges = CompareDictionaryValue(_current, _last) == false;
                    }
                }
                else
                    throw new ArgumentOutOfRangeException(key);
            }
        }

        public bool IsDefault
        {
            get { return _isDefault; }
            private set
            {
                if (_isDefault != value)
                {
                    _isDefault = value;
                    RaisePropertyChanged(() => IsDefault);
                }
            }
        }

        public bool HasChanges
        {
            get { return _hasChanges; }
            private set
            {
                if (_hasChanges != value)
                {
                    _hasChanges = value;
                    RaisePropertyChanged(() => HasChanges);
                }
            }
        }

        public Dictionary<string, object> ToDictionary()
        {
            return _current;
        }

        public Dictionary<string, object> LastToDictionary()
        {
            return _last;
        }

        public void SetFromDefault()
        {
            _current.Clear();
            foreach (var item in _default)
            {
                _current.Add(item.Key, item.Value);
                RaisePropertyChanged(item.Key);
            }

            IsDefault = true;
            HasChanges = CompareDictionaryValue(_current, _last) == false;
        }

        public void SetToLast()
        {
            _last.Clear();
            foreach (var item in _current)
            {
                _last.Add(item.Key, item.Value);
            }

            HasChanges = false;
        }
    }
}
